/*
 * This is written by Lulu Han.
 * E-mail: locomotive_crypto@163.com
 */

#include "sec_mul.h"

SecMul::CloudA::CloudA(const PrivateKey& pri): Decryptor(pri){
	// ...
}

void SecMul::CloudA::dec_reenc(const NTL::ZZ& nca, const NTL::ZZ& ncb, NTL::ZZ& cmul){
	NTL::ZZ ca, cb;
	
	Decrypt(nca, ca);
	Decrypt(ncb, cb);
	
	NTL::ZZ mul;
	
	mul = (ca * cb) % GetN();
	
	Encrypt(mul, cmul);
}

SecMul::CloudB::CloudB(const PublicKey& pub): Encryptor(pub){
	// ...
}


void SecMul::CloudB::gen_two_ciphers(const NTL::ZZ& ca, const NTL::ZZ& cb,
	NTL::ZZ& nca, NTL::ZZ& ncb){
	
	NTL::ZZ c, d;
	
	c = NTL::RandomBnd(GetN() -1 ) + 1;
	d = NTL::RandomBnd(GetN() -1 ) + 1;
	
	HE_Add_Const(ca, c, nca);
	HE_Add_Const(cb, d, ncb);
	
	NTL::ZZ cad, cbc;
	
	HE_Mul_Const(ca, GetN() - d, cad);
	HE_Mul_Const(cb, GetN() - c, cbc);
	
	NTL::ZZ cd, ccd;
	cd = GetN() - ((c * d) % GetN());
	
	Encrypt(cd, ccd);
	
	HE_Add_Cipher(cad, cbc, m_subexp);
	HE_Add_Cipher(ccd, m_subexp, m_subexp);
}

void SecMul::CloudB::gen_mul(const NTL::ZZ& cmul, NTL::ZZ& cab){
	HE_Add_Cipher(cmul, m_subexp, cab);
}
